package xyz.bali16.module.article.service.impl;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.starblues.annotation.Supplier;
import com.gitee.starblues.bootstrap.annotation.AutowiredType;
import com.google.common.base.Preconditions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xyz.bali16.application.core.utils.AuthUtils;
import xyz.bali16.application.core.utils.IDUtils;
import xyz.bali16.application.core.utils.RedisUtil;
import xyz.bali16.application.core.utils.TimeUtil;
import xyz.bali16.application.entity.User;
import xyz.bali16.application.security.PreAuthorizeService;
import xyz.bali16.application.service.UserService;
import xyz.bali16.module.article.entity.Article;
import xyz.bali16.module.article.entity.ArticleCategory;
import xyz.bali16.module.article.entity.ArticleTag;
import xyz.bali16.module.article.mapper.ArticleCategoryMapper;
import xyz.bali16.module.article.mapper.ArticleMapper;
import xyz.bali16.module.article.mapper.ArticleTagMapper;
import xyz.bali16.module.article.model.ArticleAddParam;
import xyz.bali16.module.article.model.ArticlePageParam;
import xyz.bali16.module.article.model.ArticleUpdateParam;
import xyz.bali16.module.article.service.ArticleService;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static xyz.bali16.application.core.utils.TimeUtil.parseStringToLocalDateTime;


@Service
@Supplier("article")
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    @AutowiredType(AutowiredType.Type.PLUGIN_MAIN)
    @Autowired
    UserService userService;

    @Autowired
    ArticleTagMapper articleTagMapper;
    @Autowired
    ArticleCategoryMapper articleCategoryMapper;

    @Autowired
    @AutowiredType(AutowiredType.Type.MAIN_PLUGIN)
    RedisUtil redisUtil;

    @Override
    public List<Article> supperList(List<String> ids) {
        return list(new QueryWrapper<Article>().in("id", ids));
    }

    @Override
    public boolean supperUpdateById(List<Article> articles) {
        return updateBatchById(articles);
    }

    @Override
    public IPage<Article> getPage(ArticlePageParam param) {
        IPage<?> page = new Page<>(param.getCurrent(), param.getSize());
        return this.baseMapper.getPage(page, param);
    }

    @Override
    @Transactional
    public void add(ArticleAddParam param) throws Exception {

        Preconditions.checkNotNull(param, "参数不能为为空");
        Article article = new Article();
        BeanUtils.copyProperties(param, article);
        User user = userService.getByUsername(AuthUtils.getCurrentUsername());

        if (article.getUrl() == null) {
            article.setUrl("/" + article.getUrl());
        }

        article.setUserId(user.getUserId());
        article.setId(IDUtils.uuid());
        article.setGmtCreated(TimeUtil.getNowTimeToSeconds());
        article.setGmtModified(TimeUtil.getNowTimeToSeconds());
        article.setModifiedUserId(user.getUserId());
        System.out.println("article" + article);
        // 处理tag
        List<String> tagIds = param.getTagIds();
        if (CollectionUtils.isNotEmpty(tagIds)) {
            for (String tagId : tagIds) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(article.getId());
                articleTag.setTagId(tagId);
                articleTagMapper.insert(articleTag);
            }
        }
        if (!StringUtils.isBlank(param.getCategoryId())) {
            // 处理category
            ArticleCategory articleCategory = new ArticleCategory();
            articleCategory.setCategoryId(param.getCategoryId());
            articleCategory.setArticleId(article.getId());
            articleCategoryMapper.insert(articleCategory);
        }
        save(article);
    }

    @Override
    public void update(ArticleUpdateParam param) throws Exception {
        Preconditions.checkNotNull(param, "参数不能为为空");
        Article article = new Article();
        BeanUtils.copyProperties(param, article);
        article.setGmtModified(TimeUtil.getNowTimeToSeconds());
        updateById(article);
        // 删除原有的category与tagIds
        Wrapper<ArticleTag> articleTagWrapper = Wrappers.<ArticleTag>lambdaQuery().eq(ArticleTag::getArticleId, param.getId());
        articleTagMapper.delete(articleTagWrapper);
        Wrapper<ArticleCategory> articleCategoryWrapper = Wrappers.<ArticleCategory>lambdaQuery().eq(ArticleCategory::getArticleId, param.getId());
        articleCategoryMapper.delete(articleCategoryWrapper);
        // 处理tag
        List<String> tagIds = param.getTagIds();
        if (tagIds != null && CollectionUtils.isNotEmpty(tagIds)) {
            for (String tagId : tagIds) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(article.getId());
                articleTag.setTagId(tagId);
                articleTagMapper.insert(articleTag);
            }
        }
        if (param.getCategoryId() != null) {
            // 处理category
            ArticleCategory articleCategory = new ArticleCategory();
            articleCategory.setCategoryId(param.getCategoryId());
            articleCategory.setArticleId(article.getId());
            articleCategoryMapper.insert(articleCategory);
        }
    }

    @Override
    public void delete(String tagId) throws Exception {
        if (tagId == null) {
            return;
        }
        removeById(tagId);
    }

    @Transactional
    @Override
    public void updateStatus(String articleId, int status) {
        Wrapper<Article> wrapper = Wrappers.<Article>lambdaQuery()
                .eq(Article::getId, articleId);
        Article article = new Article();
        if (status == 1) {
            article.setStatus(1);
        } else {
            article.setStatus(0);
        }
        update(article, wrapper);
    }

    @Override
    public Integer countArticle() {
        return lambdaQuery().select(Article::getId).count();
    }
    @Override
    public Article supperGetById(String id){
        return this.getById(id);
    }
}
